package com.share.rabbitmq.direct;

import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.DeliverCallback;
import com.share.rabbitmq.RabbitMQConnection;

import java.util.HashMap;
import java.util.Map;

/**
 * @desc:直接交换机消费者
 * @author:caifan
 * @date:2020/3/1
 */
public class DirectExchangeConsumer {

    public static void main(String[] args) throws Exception {
        Connection connect = RabbitMQConnection.connect();
        //创建channel
        Channel channel = connect.createChannel();

//        simpleDirectConsumer(channel);
        dlxDirect(channel);
    }

    /**
     * 死信demo
     * @param channel
     * @throws Exception
     */
    private static void dlxDirect(Channel channel) throws Exception {
        final String dlxExchange = "my.dlx.direct.exchange";
        final String dlxQueue = "my.dlx.direct.queue";

        final String exchange = "my.direct.exchange";
        final String queue = "my.direct.queue";
        final String routingKey = "my.direct.routingKey";
        //死信exchange
        channel.exchangeDeclare(dlxExchange, BuiltinExchangeType.DIRECT, true, false, null);
        channel.queueDeclare(dlxQueue, true, false, false, null);
        channel.queueBind(dlxQueue, dlxExchange, routingKey);

        //正常队列
        channel.exchangeDeclare(exchange, BuiltinExchangeType.DIRECT, true, false, null);
        Map<String, Object> argMap = new HashMap<>();
        argMap.put("x-dead-letter-exchange", dlxExchange);
        channel.queueDeclare(queue, true, false, false, argMap);
        channel.queueBind(queue, exchange, routingKey);
        DeliverCallback deliverCallback = (conuserTag, delivery) -> {
            String message = new String(delivery.getBody(), "UTF-8");
            System.out.println("message:" + message);
        };
        channel.basicConsume(queue, deliverCallback, consumerTag -> {});
    }

    /**
     * 简单使用
     * @param channel
     * @throws Exception
     */
    private static void simpleDirectConsumer(Channel channel) throws Exception {
        String exchangeName = "my.directExchange3";
        String exchangeType = "direct";
        String queueName = "my.directQueue3";
        String routingKey = "my.directExchange3.key";
        /**
         * 声明一个交换机
         * exchange:交换机的名称
         * type:交换机的类型 常见的有direct,fanout,topic等
         * durable:设置是否持久化。durable设置为true时表示持久化，反之非持久化.持久化可以将交换器存入磁盘，在服务器重启的时候不会丢失相关信息
         * autodelete:设置是否自动删除。autoDelete设置为true时，则表示自动删除。自动删除的前提是至少有一个队列或者交换器与这个交换器绑定，之后，所有与这个交换器绑定的队列或者交换器都与此解绑。
         * 不能错误的理解—当与此交换器连接的客户端都断开连接时，RabbitMq会自动删除本交换器
         * arguments:其它一些结构化的参数，比如：alternate-exchange
         */
        channel.exchangeDeclare(exchangeName,exchangeType,true,false,null);

        /**
         * 声明一个队列
         * durable:表示rabbitmq关闭删除队列
         * autodelete:表示没有程序和队列建立连接 那么就会自动删除队列
         *
         */
        channel.queueDeclare(queueName,true,false,false,null);

        /**
         * 队里和交换机绑定
         */
        channel.queueBind(queueName,exchangeName,routingKey);

        /**
         * 创建一个消费者
         */
       /* Consumer queueingConsumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consuserTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String message = new String(body, "UTF-8");
                System.out.println(envelope.getExchange() + ":" + envelope.getRoutingKey() + ":" + message);
            }
        };*/

        /**
         * 开始消费
         */
        /*channel.basicConsume(queueName,true,queueingConsumer);*/

        DeliverCallback deliverCallback = (conuserTag, delivery) -> {
            String message = new String(delivery.getBody(), "UTF-8");
            System.out.println("message:" + message);
        };
        channel.basicConsume(queueName, deliverCallback, consumerTag -> {});
    }
}
